package com.sample.command
{
	import com.sample.model.ModelLocator;
	import com.sample.remote.Delegates;
	import com.sample.remote.EntityDelegate;
	import com.sample.remote.UserServiceDelegate;
	import com.sample.vo.UserVO;
	import com.trg.flex.Callback;
	import com.trg.flex.MetaDataUtils;
	import com.trg.flex.dp.DataProvider;
	import com.trg.flex.dp.LocalDataProvider;
	import com.trg.flex.dp.LocalSearchDataProvider;
	import com.trg.flex.remote.RemoteCall;
	
	public class UserCommands
	{
		public static function get i():UserCommands {
			return new UserCommands();
		}
		
		private var userDelegate:UserServiceDelegate = Delegates.userServiceDelegate;
		private var entityDelegate:EntityDelegate = Delegates.entityDelegate;
		private var model:ModelLocator = ModelLocator.getInstance();
		
		public function addUser(user:UserVO, password:String, callback:Callback = null):void {
			var call:RemoteCall = userDelegate.addUser(user, password).addResponder(callback).addResultCallback(updateUsers);
			call.description = "Saving User";
			call.longDescription = 'Creating new user "{params.0.firstName} {params.0.lastName}"';
			call.call();
		}
		
		public function changeUserPassword(userId:Number, password:String, callback:Callback = null):void {
			var call:RemoteCall = userDelegate.changePassword(userId, password).addResponder(callback);
			call.description = "Saving password";
			call.longDescription = 'Saving new password for the user.';
			call.call();
		}
		
		public function getUserDataProvider():DataProvider {
			var dp:LocalDataProvider = new LocalDataProvider(model.users);
			return dp;
		}
		
		public function saveUser(user:UserVO, callback:Callback = null):void {
			if (user.id == 0)
				throw new Error("saveUser cannot be used to create a new user. Use addUser instead.");
			var call:RemoteCall = entityDelegate.update(user).addResponder(callback).addResultCallback(updateUsers);
			call.description = "Saving User";
			call.longDescription = 'Updating the user "{params.0.firstName} {params.0.lastName}"';
			call.call();
		}
		
		private function updateUsers(call:RemoteCall):void {
			model.cache.localCreateOrUpdate(call.result);
		}
		
		public function fetchFullUser(userId:int, callback:Callback):void {
			var call:RemoteCall = entityDelegate.fetch(MetaDataUtils.getRemoteClass(UserVO), userId).addResponder(callback).addResultCallback(updateUsers);
			call.description = "Loading User";
			call.longDescription = 'Fetching full information for the specified user.';
			call.call();
		}
	}
}